﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace StyleMVVM.Validation.Impl
{
	public sealed class RuleExecutionContext : IRuleExecutionContext
	{
		private ValidationState state = ValidationState.Valid;
		private List<IValidationRuleResultPart> parts = null;

		public RuleExecutionContext(object validationObject)
		{
			ValidationObject = validationObject;
		}

		public ValidationState State
		{
			get { return state; }
			set { state = value; }
		}

		public string Message { get; set; }

		public object ValidationObject { get; private set; }

		public void AddValidationPart(IValidationRuleResultPart part)
		{
			if (parts == null)
			{
				parts = new List<IValidationRuleResultPart>();
			}

			parts.Add(part);
		}

		public void AddRequired(string partName, string message)
		{
			if (parts == null)
			{
				parts = new List<IValidationRuleResultPart>();
			}

			if (State != ValidationState.Invalid)
			{
				State = ValidationState.InvalidRequired;
			}

			parts.Add(new ValidationRuleResultPart(null,
			                                       partName,
			                                       ValidationState.InvalidRequired,
			                                       message));

			if (string.IsNullOrEmpty(Message))
			{
				Message = message;
			}
		}

		public void AddError(string partName, string message)
		{
			State = ValidationState.Invalid;

			if (parts == null)
			{
				parts = new List<IValidationRuleResultPart>();
			}

			parts.Add(new ValidationRuleResultPart(null,
			                                       partName,
			                                       ValidationState.Invalid,
			                                       message));

			if (string.IsNullOrEmpty(Message))
			{
				Message = message;
			}
		}

		public void AddWarning(string partName, string message)
		{
			if (State == ValidationState.Valid)
			{
				State = ValidationState.ValidWithWarning;
			}

			parts.Add(new ValidationRuleResultPart
				          (null, partName, ValidationState.ValidWithWarning, message));

			if (string.IsNullOrEmpty(Message))
			{
				Message = message;
			}
		}

		public IEnumerable<IValidationRuleResultPart> ResultParts()
		{
			return parts;
		}
	}
}